#include "stdafx.h"
#include "octree_manager.h"
#include "node.h"
#include "../objects/entity.h"

//	COCTree COCTreeManager::tree;
namespace octree
{
	std::set<COCTreeNode * const> COCTreeManager::active_nodes;
	std::set<COCTreeNode * const> COCTreeManager::set_nodes;
	std::set<COCTreeNode * const> COCTreeManager::removed_nodes;

	std::set<COCTreeNode * const> COCTreeManager::subdivided_nodes;
	std::set<COCTreeNode * const> COCTreeManager::compacted_nodes;

	std::vector<std::pair<CEntity *, CEntity *> > COCTreeManager::colliding_entities;

	entity_mask_info * COCTreeManager::tmp_buff1;
	entity_mask_info * COCTreeManager::tmp_buff2;

	bool COCTreeManager::allowSubdividedPush;

	void COCTreeManager::init(unsigned long tmp_buff_sz)
	{
		tmp_buff1 = toolkit::allocateMemory<entity_mask_info>(tmp_buff_sz);
		tmp_buff2 = toolkit::allocateMemory<entity_mask_info>(tmp_buff_sz);
		allowSubdividedPush = false;
	}


	COCTree * const COCTreeManager::getRoot()
	{
		static COCTree root;
		return & root;
	}

	/*
	void COCTreeManager::processCollisions(void)
	{
		for (std::vector<std::pair<CEntity *, CEntity *> >::const_iterator it = colliding_entities.begin(); it != colliding_entities.end(); it++)
		{
			CEntity * from = (*it).first;
			CEntity * to = (*it).second;

			from->colide(*to);
		}
		colliding_entities.clear();
	}
	*/

	void COCTreeManager::drawActiveNodes(void(*drawFunc)(const __m128 & pos))
	{
		for (std::set<COCTreeNode * const>::const_iterator it = active_nodes.begin(); it != active_nodes.end(); it++)
		{
			if (0 >= (*it)->getEntityCount())
				glColor4f(0.7f, 0.1f, 0.1f, 0.4f);
			else
				glColor4f(0.1f, 0.5f, 0.1f, 0.4f);
			drawFunc((*it)->getCenter());
		}
			// boost::bind(CRenderer::drawOctreeNode, (*it)->getCenter());
	}

	void COCTreeManager::updateActiveNodes(void)
	{
		colliding_entities.clear();
		for (std::set<COCTreeNode * const>::const_iterator it = compacted_nodes.begin(); it != compacted_nodes.end(); it++)
			(*it)->compact_();
		compacted_nodes.clear();

		for (std::set<COCTreeNode * const>::const_iterator it = subdivided_nodes.begin(); it != subdivided_nodes.end(); it++)
			(*it)->subdivide_();
		subdivided_nodes.clear();

		active_nodes.insert(set_nodes.begin(), set_nodes.end());
		for (std::set<COCTreeNode * const>::const_iterator it = removed_nodes.begin(); it != removed_nodes.end(); it++)
			active_nodes.erase(*it);

		removed_nodes.clear();
		set_nodes.clear();

		std::set<COCTreeNode * const>::const_iterator it = active_nodes.begin();
		for (; it != active_nodes.end(); it++)
		{
			(*it)->update();
			(*it)->testCollisions();
		}

		for (std::vector<std::pair<CEntity *, CEntity *> >::const_iterator it = colliding_entities.begin(); it != colliding_entities.end(); it++)
		{
			CEntity * const from = (*it).first;
			CEntity * const to = (*it).second;

			from->collide(*to);
		}
		
	}

} // namespace octree